#include <iostream>

//reference from effective c++

class Airplane {
private:
    struct Data {
        unsigned int ui;
        char c;
    };

    union {
        Data _Data{ 512, 'k' };
        Airplane* Next;
    };

    static Airplane* HeadOfList;
    static constexpr unsigned int BlockSize = 512;

public:
    Airplane() { std::cout << "Airplane::Airplane()" << std::endl; }
    ~Airplane() { std::cout << "Airplane::~Airplane()" << std::endl; }

public:
    void* operator new(std::size_t)
    {
        Airplane* p = HeadOfList;
        if (p)
            HeadOfList = HeadOfList->Next;

        else {
            Airplane* newBlock = static_cast<Airplane*>
                (::operator new(sizeof(Airplane) * BlockSize));

            for (int i = 1; i < BlockSize - 1; i++)
                newBlock[i].Next = &newBlock[i + 1];
            
            newBlock[BlockSize - 1].Next = nullptr;

            p = newBlock;
            HeadOfList = &newBlock[1];
        }

        return p;
    }

    void operator delete(void* ptr)
    {
        if (ptr == nullptr)
            return;

        Airplane* p = static_cast<Airplane*>(ptr);

        p->Next = HeadOfList;
        HeadOfList = p;
    }
};

Airplane* Airplane::HeadOfList = nullptr;

int main() {
    union u {
        uint32_t a;
        char c;
    }_u;

    _u.a = 0xffffff61;
    std::cout << std::hex << _u.a << std::endl;
    std::cout << _u.c << std::endl;

    _u.c = 'A';
    std::cout << std::hex << _u.a << std::endl;
    std::cout << _u.c << std::endl;

    std::cout << "sizeof(Airplane): " << sizeof(Airplane) << std::endl;

    Airplane* a = new Airplane();
    Airplane* b = new Airplane();
    Airplane* c = new Airplane();

    delete b;

    Airplane* d = new Airplane();
    Airplane* e = new Airplane();

    free(a);

    return 0;
}